package com.ruoyi.lock.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.lock.domain.ATenantuser;
import com.ruoyi.lock.domain.SSchoolUser;
import com.ruoyi.lock.domain.AHomeUser;
import com.ruoyi.lock.domain.ABuildHome;
import com.ruoyi.lock.domain.ATenantkey;
import com.ruoyi.lock.mapper.ATenantuserMapper;
import com.ruoyi.lock.mapper.AHomeUserMapper;
import com.ruoyi.lock.mapper.AOpenlockMapper;
import com.ruoyi.lock.mapper.ATenantkeyMapper;
import com.ruoyi.lock.service.IATenantuserService;
import com.ruoyi.lock.service.IABuildHomeService;
import com.ruoyi.lock.service.IOracleDataSyncService;
import com.ruoyi.lock.task.BatchResult;
import com.ruoyi.locksApi.service.LockApiService;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.locksApi.service.impl.ApartmentTokenTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.ruoyi.common.utils.StringUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Date;

/**
 * Oracle数据同步服务实现
 * 
 * @author ruoyi
 * @date 2025-01-27
 */

@Slf4j
@Service
public class OracleDataSyncServiceImpl implements IOracleDataSyncService {

    @Value("${spring.profiles.active:dev}")
    private String activeProfile;

    @Autowired(required = false)
    @Qualifier("oracleJdbcTemplate")
    private JdbcTemplate oracleJdbcTemplate;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private IATenantuserService aTenantuserService;

    @Autowired
    private ATenantuserMapper aTenantuserMapper;

    @Autowired
    private AHomeUserMapper aHomeUserMapper;

    @Autowired
    private IABuildHomeService aBuildHomeService;

    @Autowired
    private LockApiService lockApiService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ApartmentTokenTask apartmentTokenTask;

    @Autowired
    private AOpenlockMapper aOpenlockMapper;

    @Autowired
    private ATenantkeyMapper aTenantkeyMapper;

    @Override
    public void syncOracleUserCard(String type) {
        if ("center".equals(activeProfile)) {
           log.info("当前环境是center，跳过Oracle查询");
            return;
        }

        try {
           log.info("开始调用外部接口查询Oracle用户卡信息...");

            String timeParam;
            if ("all".equals(type)) {
                // 查询2020年以后的数据
                timeParam = "2020-01-01 00:00:00";
               log.info("查询类型: all，查询2020年以后的所有数据");
            } else if ("current".equals(type)) {
                // 处理 "current" 类型：自动获取数据库中的最大更新时间
                try {
                    Date maxUpdateTime = aTenantuserService.getMaxSUpdateTime();
                    if (maxUpdateTime != null) {
                        // 有数据，使用数据库中的最大更新时间
                        SimpleDateFormat oracleSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        timeParam = oracleSdf.format(maxUpdateTime);
                        log.info("查询类型: current，自动获取数据库最大更新时间: {}", timeParam);
                    } else {
                        // 没有数据，回退到全量同步
                        log.info("查询类型: current，数据库中没有s_update_time数据，回退到全量同步");
                        timeParam = "2020-01-01 00:00:00";
                    }
                } catch (Exception e) {
                    log.error("获取数据库最大更新时间失败，使用当前时间作为备选", e);
                    timeParam = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                }
            } else {
                // 其他类型，查询当前时间的数据
                timeParam = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                log.info("查询类型: {}，查询当前时间的数据", type);
            }

            // 直接使用原始时间参数，不进行URL编码
            String url = "http://10.30.100.21:8886/api/usercards/updatetime?time=" + timeParam;

           log.info("时间参数: " + timeParam);
           log.info("请求URL: " + url);

            // 调用外部接口
            String response = null;
            try {
                // 创建HttpHeaders，模拟浏览器请求
                org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
                headers.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36");
                headers.set("Accept", "application/json, text/plain, */*");
                headers.set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8");
                headers.set("Connection", "keep-alive");

                org.springframework.http.HttpEntity<String> entity = new org.springframework.http.HttpEntity<>(headers);

               log.info("发送请求头: " + headers);
               log.info("开始调用Oracle接口，请耐心等待（超时时间设置为5分钟）...");

                response = restTemplate.exchange(url, org.springframework.http.HttpMethod.GET, entity, String.class).getBody();
               log.info("接口响应状态: 成功");
               log.info("接口响应内容: " + response);
            } catch (Exception e) {
                log.info("调用Oracle接口失败: " + e.getMessage());
                log.info("请求URL: " + url);
                e.printStackTrace();
                return;
            }

            if (response == null || response.trim().isEmpty()) {
                log.info("接口返回空响应");
                return;
            }

            // 解析JSON响应
            if (response != null && !response.trim().isEmpty()) {
                JSONObject jsonResponse = JSON.parseObject(response);
                JSONArray dataArray = jsonResponse.getJSONArray("data");

                if (dataArray != null && !dataArray.isEmpty()) {
                    List<SSchoolUser> userList = new ArrayList<>();



                    for (int i = 0; i < dataArray.size(); i++) {
                        JSONObject userJson = dataArray.getJSONObject(i);
                        SSchoolUser user = new SSchoolUser();

                        // 映射字段
                        user.setUserId(userJson.getString("userId"));
                        user.setUserName(userJson.getString("username"));
                        user.setUserNumb(userJson.getString("userNumb"));
                        user.setSex(userJson.getLong("sex"));
                        user.setDeptName(userJson.getString("deptName"));
                        user.setCategory(userJson.getLong("category"));
                        user.setUserStatus(userJson.getLong("userStatus"));
                        // 处理cardNo字段（可能为null）
                        Object cardNoObj = userJson.get("cardNo");
                        if (cardNoObj != null && !"null".equals(cardNoObj.toString())) {
                            user.setCardNo(Long.valueOf(cardNoObj.toString()));
                        }
                        user.setFactoryFixId(userJson.getString("factoryFixId"));
                        user.setCardStatus(userJson.getLong("cardStatus"));
                        
                        // 处理updateTime字段
                        String updateTime = userJson.getString("updateTime");
                        if (updateTime != null) {
                            user.setUpdateTime(updateTime);
                        }

                        userList.add(user);
                    }
                   log.info("成功解析 " + userList.size() + " 条用户数据");

                    // 分批处理数据，避免内存溢出和处理超时
                    int batchSize = 1000; // 每批处理1000条
                    int totalBatches = (userList.size() + batchSize - 1) / batchSize; // 计算总批次数

                   log.info("开始分批处理数据，总批次数: " + totalBatches + "，每批大小: " + batchSize);

                    int totalNewUsers = 0;
                    int totalUpdatedUsers = 0;
                    int totalUnchangedUsers = 0;

                    for (int batchIndex = 0; batchIndex < totalBatches; batchIndex++) {
                        int startIndex = batchIndex * batchSize;
                        int endIndex = Math.min(startIndex + batchSize, userList.size());
                        List<SSchoolUser> batch = userList.subList(startIndex, endIndex);

                       log.info("处理第 " + (batchIndex + 1) + "/" + totalBatches + " 批，数据范围: " + startIndex + "-" + (endIndex - 1));

                        // 处理当前批次
                        BatchResult result = processBatch(batch);

                        totalNewUsers += result.getNewUsers();
                        totalUpdatedUsers += result.getUpdatedUsers();
                        totalUnchangedUsers += result.getUnchangedUsers();

                       log.info("第 " + (batchIndex + 1) + " 批处理完成: 新用户=" + result.getNewUsers() +
                                ", 更新=" + result.getUpdatedUsers() + ", 无变化=" + result.getUnchangedUsers());

                        // 每批处理完后稍作休息，避免系统压力过大
                        if (batchIndex < totalBatches - 1) {
                            try {
                                Thread.sleep(100); // 休息100毫秒
                            } catch (InterruptedException e) {
                                Thread.currentThread().interrupt();
                                break;
                            }
                        }
                    }

                   log.info("所有批次处理完成！");
                   log.info("数据对比总结果:");
                   log.info("  新用户: " + totalNewUsers + " 条");
                   log.info("  需要更新: " + totalUpdatedUsers + " 条");
                   log.info("  无变化: " + totalUnchangedUsers + " 条");

                   log.info("数据保存完成，总共保存/更新 " + (totalNewUsers + totalUpdatedUsers) + " 条用户数据到数据库");
                } else {
                   log.info("接口返回数据为空");
                }
            }

           log.info("Oracle用户卡查询完成");

        } catch (Exception e) {
            log.info("调用Oracle接口失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 将性别代码转换为中文文本
     *
     * @param gender 性别代码
     * @return 性别中文文本
     */
    private String getGenderText(Long gender) {
        if (gender == null) {
            return "未知";
        }
        return gender == 1L ? "男" : "女";
    }

    /**
     * 将Oracle的userStatus转换为系统的flg_delete状态
     * Oracle: userStatus=0(正常) -> 系统: flg_delete='1'(正常)
     * Oracle: userStatus=1(注销) -> 系统: flg_delete='0'(删除)
     *
     * @param oracleUserStatus Oracle的用户状态
     * @return 系统的flg_delete状态
     */
    private String convertOracleStatusToSystemStatus(Long oracleUserStatus) {
        if (oracleUserStatus == null) {
            return "1"; // 默认为正常状态
        }
        // Oracle的0(正常) -> 系统的'1'(正常)
        // Oracle的1(注销) -> 系统的'0'(删除)
        return oracleUserStatus == 0L ? "1" : "0";
    }

    /**
     * 将系统状态转换为中文文本
     *
     * @param status 系统状态
     * @return 状态中文文本
     */
    private String getStatusText(String status) {
        if (status == null || status.isEmpty()) {
            return "未知";
        }
        return "1".equals(status) ? "正常" : "删除";
    }

    /**
     * 处理单个批次的数据
     *
     * @param batch 批次数据
     * @return 处理结果
     */
    private BatchResult processBatch(List<SSchoolUser> batch) {
        // 提取学工号列表用于对比
        List<String> userNumbs = new ArrayList<>();
        for (SSchoolUser user : batch) {
            if (user.getUserNumb() != null && !user.getUserNumb().trim().isEmpty()) {
                userNumbs.add(user.getUserNumb());
            }
        }

        // 根据学工号查询现有租户数据
        List<ATenantuser> existingTenants = aTenantuserService.selectATenantuserByIdCardNumbers(userNumbs);

        // 创建学工号到现有租户的映射
        Map<String, ATenantuser> existingTenantMap = new HashMap<>();
        for (ATenantuser tenant : existingTenants) {
            if (tenant.getIdCardNumber() != null) {
                existingTenantMap.put(tenant.getIdCardNumber(), tenant);
            }
        }

        // 对比数据并输出差异
        int newUsers = 0;
        int updatedUsers = 0;
        int unchangedUsers = 0;

        for (SSchoolUser oracleUser : batch) {
            if (oracleUser.getUserNumb() == null || oracleUser.getUserNumb().trim().isEmpty()) {
                continue;
            }

            ATenantuser existingTenant = existingTenantMap.get(oracleUser.getUserNumb());

            if (existingTenant == null) {
                // 新用户
                newUsers++;
               log.info("新用户: " + oracleUser.getUserName() + " (学工号: " + oracleUser.getUserNumb() + ")");
                
                // 执行数据库插入
                try {
                    ATenantuser newTenant = new ATenantuser();
                    newTenant.setName(oracleUser.getUserName());
                    newTenant.setIdCardNumber(oracleUser.getUserNumb());

                    newTenant.setSFactoryFixId(oracleUser.getFactoryFixId());
                    // 性别映射：Oracle的1=男, 2=女 -> MySQL的1=男, 2=女
                    newTenant.setGender(oracleUser.getSex().toString());
                    newTenant.setRemark(oracleUser.getDeptName());
                    
                    // 根据部门名称设置小区ID
                    if (oracleUser.getDeptName() != null && oracleUser.getDeptName().contains("菱湖校区")) {
                        newTenant.setCellId(17L);
                    }else if (oracleUser.getDeptName() != null && oracleUser.getDeptName().contains("新桥")) {
                        newTenant.setCellId(15L);
                    }else {
                        newTenant.setCellId(0L);
                    }
                    
                    newTenant.setFlgDelete(convertOracleStatusToSystemStatus(oracleUser.getUserStatus()));

                    Long category = oracleUser.getCategory();
                    // 根据Oracle的category设置用户类型
                    if (category != null && category == 28L) {
                        newTenant.setType("0");
                    } else {
                        newTenant.setType("1");
                    }
                    newTenant.setPhone(oracleUser.getUserNumb()); // 默认空手机号
                    
                    // 处理物理卡号（十六进制转十进制）
                    if (oracleUser.getFactoryFixId() != null && !oracleUser.getFactoryFixId().trim().isEmpty()) {
                        try {
                            String hexCardId = oracleUser.getFactoryFixId().trim();
                            Long decimalCardId = Long.parseLong(hexCardId, 16);
                            String formattedCardId = String.format("%010d", decimalCardId);
                            newTenant.setCardNo(formattedCardId);
                        } catch (NumberFormatException e) {
                            log.info("物理卡号格式错误: " + oracleUser.getFactoryFixId() + " (学工号: " + oracleUser.getUserNumb() + ")");
                        }
                    }
                    
                    if (oracleUser.getUpdateTime() != null) {
                        newTenant.setSUpdateTime(oracleUser.getUpdateTime());
                    }
                    
                    int insertResult = aTenantuserMapper.insertATenantuser(newTenant);
                   log.info("✅ 新用户插入成功 (学工号: " + oracleUser.getUserNumb() + "): " + insertResult + " 行受影响");
                } catch (Exception e) {
                    log.info("❌ 新用户插入失败 (学工号: " + oracleUser.getUserNumb() + "): " + e.getMessage());
                    // 插入失败时不计入新用户统计
                    newUsers--;
                }

            } else {
                // 检查是否有更新
                boolean hasUpdate = false;

                // 检查基本信息变更
                String oldName = existingTenant.getName();
                String newName = oracleUser.getUserName();
                Long oldGender = Long.valueOf(existingTenant.getGender());
                Long newGender = oracleUser.getSex();

                // 检查部门信息变更（Oracle的deptName映射到MySQL的remark）
                String oldDeptName = existingTenant.getRemark();
                String newDeptName = oracleUser.getDeptName();
                
                // 检查用户类型变更（Oracle的category映射到MySQL的type）
                String oldType = existingTenant.getType();
                String newType;
                Long category = oracleUser.getCategory();
                if (category != null && category == 28L) {
                    newType = "0";
                } else {
                    newType = "1";
                }
                
                // 检查状态变更（Oracle的userStatus与系统的flg_delete相反）
                String oldStatus = existingTenant.getFlgDelete();
                Long oracleUserStatus = oracleUser.getUserStatus();
                String newStatus = convertOracleStatusToSystemStatus(oracleUserStatus);
                
                boolean nameChanged = !newName.equals(oldName);
                boolean genderChanged = !newGender.equals(oldGender);
                boolean deptNameChanged = !newDeptName.equals(oldDeptName);
                boolean typeChanged = !newType.equals(oldType);
                boolean statusChanged = !newStatus.equals(oldStatus);

                // 处理基本信息变更（姓名、性别、部门和用户类型）
                if (nameChanged || genderChanged || deptNameChanged || typeChanged) {
                    hasUpdate = true;
                    
                    // 构建基本信息变更信息
                    String changeMsg = "基本信息变更 (学工号: " + oracleUser.getUserNumb() + "): ";
                    
                    if (nameChanged) {
                        changeMsg += "姓名 " + oldName + " -> " + newName;
                    }
                    
                    if (nameChanged && (genderChanged || deptNameChanged || typeChanged)) {
                        changeMsg += ", ";
                    }
                    
                    if (genderChanged) {
                        String oldGenderText = getGenderText(oldGender);
                        String newGenderText = getGenderText(newGender);
                        changeMsg += "性别 " + oldGenderText + " -> " + newGenderText;
                    }
                    
                    if ((nameChanged || genderChanged) && (deptNameChanged || typeChanged)) {
                        changeMsg += ", ";
                    }
                    
                    if (deptNameChanged) {
                        changeMsg += "部门 " + oldDeptName + " -> " + newDeptName;
                    }
                    
                    if ((nameChanged || genderChanged || deptNameChanged) && typeChanged) {
                        changeMsg += ", ";
                    }
                    
                    if (typeChanged) {
                        String oldTypeText = "0".equals(oldType) ? "学生" : "教职工";
                        String newTypeText = "0".equals(newType) ? "学生" : "教职工";
                        changeMsg += "用户类型 " + oldTypeText + " -> " + newTypeText;
                    }
                    
                   log.info(changeMsg);
                    
                    // 执行数据库更新
                    try {
                        int updateResult = aTenantuserMapper.updateBasicInfo(
                            existingTenant.getId(),
                            newName,
                            newGender.toString(),
                            newDeptName,
                            newType,
                            oracleUser.getUpdateTime()
                        );
                       log.info("✅ 数据库更新成功 (学工号: " + oracleUser.getUserNumb() + "): " + updateResult + " 行受影响");
                    } catch (Exception e) {
                        log.info("❌ 数据库更新失败 (学工号: " + oracleUser.getUserNumb() + "): " + e.getMessage());
                    }
                }

                // 单独处理状态变更
                if (statusChanged) {
                    hasUpdate = true;
                    String oldStatusText = getStatusText(oldStatus);
                    String newStatusText = getStatusText(newStatus);
                   log.info("状态变更 (学工号: " + oracleUser.getUserNumb() + "): " + oldStatusText + " -> " + newStatusText);
                    
                    // 不管是否入住，都更新删除状态和s_update_time
                    try {
                        int statusUpdateResult = aTenantuserMapper.updateUserStatus(
                            existingTenant.getId(),
                            newStatus,
                            oracleUser.getUpdateTime()
                        );
                       log.info("✅ 状态和s_update_time更新成功 (学工号: " + oracleUser.getUserNumb() + "): " + statusUpdateResult + " 行受影响");
                    } catch (Exception e) {
                        log.info("❌ 状态更新失败 (学工号: " + oracleUser.getUserNumb() + "): " + e.getMessage());
                    }
                    
                    // 如果Oracle状态变更为注销（userStatus=1），还需要执行退房操作
                    if (oracleUser.getUserStatus() != null && oracleUser.getUserStatus() == 1L) {
                        handleUserStatusCancellation(existingTenant, oracleUser.getUserNumb());
                    }
                }

                // 检查物理卡号是否变更（将十六进制转换为十进制进行比较）
                else if (oracleUser.getFactoryFixId() != null && !oracleUser.getFactoryFixId().trim().isEmpty()) {
                    try {
                        // 将十六进制转换为十进制
                        String hexCardId = oracleUser.getFactoryFixId().trim();
                        Long decimalCardId = Long.parseLong(hexCardId, 16);
                        String formattedCardId = String.format("%010d", decimalCardId); // 不足10位前面补0

                        // 与现有的cardNo进行比较
                        String existingCardNo = existingTenant.getCardNo() != null ? existingTenant.getCardNo().toString() : "";
                        if (!formattedCardId.equals(existingCardNo)) {
                            hasUpdate = true;
                           log.info("物理卡号变更: " + existingCardNo + " -> " + formattedCardId + " (学工号: " + oracleUser.getUserNumb() + ", 十六进制: " + hexCardId + ")");

                            // 处理物理卡号变更
                            handleCardNumberChange(existingTenant, oracleUser, formattedCardId);
                        }
                    } catch (NumberFormatException e) {
                        log.info("物理卡号格式错误: " + oracleUser.getFactoryFixId() + " (学工号: " + oracleUser.getUserNumb() + ")");
                    }
                }

                if (hasUpdate) {
                    updatedUsers++;
                } else {
                    unchangedUsers++;
                }
            }
        }

        return new BatchResult(newUsers, updatedUsers, unchangedUsers);
    }

    /**
     * 处理用户状态注销 - 检查入住情况并执行退房
     *
     * @param tenantUser 用户信息
     * @param userNumb 学工号
     */
    private void handleUserStatusCancellation(ATenantuser tenantUser, String userNumb) {
        try {
            if (tenantUser == null || tenantUser.getId() == null) {
               log.info("用户信息为空，无法执行退房检查 (学工号: " + userNumb + ")");
                return;
            }

            // 查询用户是否有入住房间
            List<AHomeUser> homeUsers = aHomeUserMapper.selectActiveHomeUserByUserId(tenantUser.getId());
            
            if (homeUsers == null || homeUsers.isEmpty()) {
               log.info("用户未入住任何房间，无需退房 (学工号: " + userNumb + ")");
                return;
            }

           log.info("检测到用户状态注销，开始执行退房操作 (学工号: " + userNumb + ", 入住房间数: " + homeUsers.size() + ")");

            // 调用退房业务逻辑
            JSONObject checkOutResult = performApartmentRoomCheckOut(tenantUser.getId());
            
            if (checkOutResult != null) {
                Integer resultCode = checkOutResult.getInteger("resultCode");
                if (resultCode != null && resultCode == 200) {
                   log.info("✅ 用户退房成功 (学工号: " + userNumb + ")");
                } else {
                    log.info("❌ 用户退房失败 (学工号: " + userNumb + "): " + checkOutResult.getString("reason"));
                }
            } else {
                log.info("❌ 用户退房失败 (学工号: " + userNumb + "): 退房结果为空");
            }

        } catch (Exception e) {
            log.info("处理用户状态注销时发生异常 (学工号: " + userNumb + "): " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 执行公寓退房业务逻辑
     * 基于LockApiController.apartmentRoomCheckOut的逻辑
     *
     * @param userId 用户ID
     * @return 退房结果
     */
    private JSONObject performApartmentRoomCheckOut(Long userId) {
        try {
            // 根据用户ID查询用户信息
            ATenantuser aTenantuser = aTenantuserService.selectATenantuserById2(userId);
            if (aTenantuser == null) {
                JSONObject error = new JSONObject();
                error.put("resultCode", 500002);
                error.put("reason", "用户不存在");
                return error;
            }

            // 查询用户关联的房间
            List<AHomeUser> homeUsers = aHomeUserMapper.selectActiveHomeUserByUserId(userId);
            if (homeUsers == null || homeUsers.isEmpty()) {
                JSONObject error = new JSONObject();
                error.put("resultCode", 500003);
                error.put("reason", "该用户未入住任何房间");
                return error;
            }

            // 获取token
            String tokenId = redisCache.getCacheObject("apartment:token");
            if (tokenId == null) {
                // 自动登录获取token
                apartmentTokenTask.refreshToken();
                tokenId = redisCache.getCacheObject("apartment:token");
                if (tokenId == null) {
                    JSONObject error = new JSONObject();
                    error.put("resultCode", 500005);
                    error.put("reason", "tokenId不存在或已过期，自动登录失败");
                    return error;
                }
            }

            // 处理每个房间的退房
            int totalRooms = homeUsers.size();
            int successCount = 0;
            int failedCount = 0;
            List<Map<String, Object>> failedRooms = new ArrayList<>();

            for (AHomeUser homeUser : homeUsers) {
                Map<String, Object> result = processRoomCheckOut(homeUser, aTenantuser, tokenId);
                if ((Boolean) result.getOrDefault("success", false)) {
                    successCount++;
                    // 软删除入住信息
                    aHomeUserMapper.softDeleteByUserIdAndHomeId(userId, homeUser.getHomeId());

                    aOpenlockMapper.deleteAOpenlockByHomeIdAndUserId(homeUser.getHomeId(), userId);
                    aTenantkeyMapper.deleteATenantkeyByHomeIdAndTenantIdRel(homeUser.getHomeId(), userId);
                } else {
                    failedCount++;
                    ABuildHome room = aBuildHomeService.selectABuildHomeById(homeUser.getHomeId());
                    Map<String, Object> failedRoom = new HashMap<>();
                    failedRoom.put("roomName", room != null ? room.getRoomName() : "未知房间");
                    failedRoom.put("roomId", homeUser.getHomeId());
                    failedRoom.put("errorReason", result.getOrDefault("error", "未知错误"));
                    failedRooms.add(failedRoom);
                }
            }

            // 构建返回结果
            JSONObject response = new JSONObject();
            if (failedCount == 0) {
                // 全部成功
                response.put("resultCode", 200);
                response.put("reason", "退房成功");
                response.put("totalRooms", totalRooms);
                response.put("successCount", successCount);
                response.put("failedCount", failedCount);
            } else if (successCount > 0) {
                // 部分成功
                response.put("resultCode", 500008);
                response.put("reason", "部分房间退房失败");
                response.put("totalRooms", totalRooms);
                response.put("successCount", successCount);
                response.put("failedCount", failedCount);
                response.put("failedRooms", failedRooms);
            } else {
                // 全部失败
                response.put("resultCode", 500006);
                response.put("reason", "退房失败");
                response.put("totalRooms", totalRooms);
                response.put("successCount", successCount);
                response.put("failedCount", failedCount);
                response.put("failedRooms", failedRooms);
            }

            return response;

        } catch (Exception e) {
            log.info("执行退房业务逻辑时发生异常: " + e.getMessage());
            e.printStackTrace();
            JSONObject error = new JSONObject();
            error.put("resultCode", 500006);
            error.put("reason", "退房处理异常: " + e.getMessage());
            return error;
        }
    }

    /**
     * 处理单个房间退房
     * 基于LockApiController.processRoomCheckOut的逻辑
     *
     * @param homeUser 入住信息
     * @param aTenantuser 用户信息
     * @param tokenId token
     * @return 处理结果
     */
    private Map<String, Object> processRoomCheckOut(AHomeUser homeUser, ATenantuser aTenantuser, String tokenId) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 获取房间信息
            ABuildHome aBuildHome = aBuildHomeService.selectABuildHomeById(homeUser.getHomeId());
            if (aBuildHome == null) {
                result.put("success", false);
                result.put("error", "房间信息不存在");
                return result;
            }

            // 将房间ID转换为字符串，用户ID作为邮箱参数传递
            String roomId = aBuildHome.getRoomNum();
            String email = aTenantuser.getIdCardNumber() + "@hflz.com";

           log.info("开始退房: 房间=" + roomId + ", 用户=" + email);

            // 调用退房服务
            JSONObject lockApiResult = lockApiService.apartmentRoomSingleCheckOut(roomId, email);

            if (lockApiResult != null) {
                int resultCode = lockApiResult.getIntValue("resultCode");
                if (resultCode == 0||resultCode == 500003||resultCode == 500004||resultCode == 700001) {
                    result.put("success", true);
                    result.put("message", "退房成功");
                   log.info("房间退房成功: " + roomId);
                } else {
                    result.put("success", false);
                    result.put("error", lockApiResult.getString("reason"));
                    log.info("房间退房失败: " + roomId + ", 原因: " + lockApiResult.getString("reason"));
                }
            } else {
                result.put("success", false);
                result.put("error", "退房服务返回空结果");
            }

        } catch (Exception e) {
            result.put("success", false);
            result.put("error", "退房处理异常: " + e.getMessage());
            log.info("处理房间退房时发生异常: " + e.getMessage());
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 处理物理卡号变更
     * 如果没有入住：直接更新卡号和s_update_time
     * 如果有入住：退房 → 更新卡号 → 重新入住
     *
     * @param tenantUser 用户信息
     * @param oracleUser Oracle用户信息
     * @param newCardNo 新卡号
     */
    private void handleCardNumberChange(ATenantuser tenantUser, SSchoolUser oracleUser, String newCardNo) {
        try {
            if (tenantUser == null || tenantUser.getId() == null) {
               log.info("用户信息为空，无法处理卡号变更 (学工号: " + oracleUser.getUserNumb() + ")");
                return;
            }

            // 查询用户是否有卡片类型的钥匙
            List<ATenantkey> cardKeys = aTenantkeyMapper.selectCardKeysByUserId(tenantUser.getId());
            
            if (cardKeys == null || cardKeys.isEmpty()) {
                // 没有卡片钥匙，直接更新卡号和s_update_time
               log.info("用户没有卡片类型钥匙，直接更新卡号 (学工号: " + oracleUser.getUserNumb() + ")");
                updateCardNoAndTime(tenantUser.getId(), newCardNo, oracleUser.getUpdateTime(), oracleUser.getFactoryFixId());
                return;
            }

            log.info("用户有卡片类型钥匙，开始删除旧钥匙并添加新钥匙流程 (学工号: " + oracleUser.getUserNumb() + ", 卡片钥匙数: " + cardKeys.size() + ")");

            // 1. 删除旧的卡片钥匙
            boolean deleteSuccess = deleteOldCardKeys(tenantUser.getId(), cardKeys);
            
            if (!deleteSuccess) {
                log.info("❌ 删除旧钥匙失败，跳过后续流程 (学工号: " + oracleUser.getUserNumb() + ")");
                return;
            }
            // 2. 更新卡号和s_update_time
            updateCardNoAndTime2(tenantUser.getId(), newCardNo, oracleUser.getUpdateTime(), oracleUser.getFactoryFixId());
            // 3. 添加新的卡片钥匙
            //新的卡号
//            tenantUser.setCardNo(newCardNo);
//            tenantUser.setName(oracleUser.getUserName());
//                addNewCardKeys(tenantUser, cardKeys, oracleUser.getUserNumb());

        } catch (Exception e) {
            log.info("处理卡号变更时发生异常 (学工号: " + oracleUser.getUserNumb() + "): " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 更新卡号、s_update_time和s_factory_fix_id
     */
    private void updateCardNoAndTime(Long userId, String newCardNo, String updateTime, String factoryFixId) {
        try {
            // 更新卡号、时间和工厂固定ID
            int updateResult = aTenantuserMapper.updateCardNo(userId, newCardNo, updateTime, factoryFixId);
           log.info("✅ 卡号、时间和工厂固定ID更新成功: " + updateResult + " 行受影响");

        } catch (Exception e) {
            log.info("❌ 更新卡号、时间和工厂固定ID失败: " + e.getMessage());
        }
    }
    
    private void updateCardNoAndTime2(Long userId, String newCardNo, String updateTime, String factoryFixId) {
        try {
            // 更新卡号、时间和工厂固定ID
            int updateResult = aTenantuserMapper.updateCardNo2(userId, newCardNo, updateTime, factoryFixId);
           log.info("✅ 卡号、时间和工厂固定ID更新成功: " + updateResult + " 行受影响");

        } catch (Exception e) {
            log.info("❌ 更新卡号、时间和工厂固定ID失败: " + e.getMessage());
        }
    }

    /**
     * 删除旧的卡片钥匙
     */
    private boolean deleteOldCardKeys(Long userId, List<ATenantkey> cardKeys) {
        try {
            ATenantuser aTenantuser = aTenantuserService.selectATenantuserById2(userId);
            if (aTenantuser == null) {
                log.info("❌ 用户信息不存在，无法退房");
                return false;
            }

            for (ATenantkey cardKey : cardKeys) {
                // 调用门锁删除钥匙API
                ABuildHome aBuildHome = aBuildHomeService.selectABuildHomeById(cardKey.getHomeId());
                if (aBuildHome != null) {
                    String roomId = aBuildHome.getRoomNum();
                    String keyId = cardKey.getPwdId(); // 获取门锁钥匙ID

                   log.info("开始删除门锁钥匙: 房间=" + roomId + ", 钥匙ID=" + keyId);

                    if (keyId != null && !keyId.trim().isEmpty()) {
                        JSONObject lockApiResult = lockApiService.apartmentDelKey(keyId);
                        if ( lockApiResult.getIntValue("resultCode") == 0||lockApiResult.getIntValue("resultCode") == 500002) {
                           log.info("门锁钥匙删除成功: " + keyId);
                        } else {
                            log.info("门锁钥匙删除失败: " + keyId + ", 原因: " + (lockApiResult != null ? lockApiResult.getString("reason") : "未知"));
                            // 继续处理，不因为门锁API失败而停止
                        }
                    } else {
                       log.info("钥匙ID为空，跳过门锁删除操作");
                    }
                }

                // 删除该用户在这个房间的开门记录
                aOpenlockMapper.deleteAOpenlockByHomeIdAndUserId(cardKey.getHomeId(), userId);
               log.info("✅ 删除开门记录成功，用户ID: " + userId + ", 房间ID: " + cardKey.getHomeId());
                
                // 删除钥匙记录
                aTenantkeyMapper.deleteATenantkeyByHomeIdAndTenantIdRel(cardKey.getHomeId(), userId);
               log.info("✅ 删除钥匙记录成功，用户ID: " + userId + ", 房间ID: " + cardKey.getHomeId());
            }
            return true;
        } catch (Exception e) {
            log.info("❌ 删除旧钥匙失败: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 添加新的卡片钥匙（使用新卡号和原来的时间信息）
     */
//    private void addNewCardKeys(ATenantuser tenantUser, List<ATenantkey> originalCardKeys, String userNumb) {
//        try {
//            for (ATenantkey originalCardKey : originalCardKeys) {
//                                 ABuildHome room = aBuildHomeService.selectABuildHomeById(originalCardKey.getHomeId());
//                 if (room != null) {
//                     String roomNum = room.getRoomNum();
//
//                     // 先查询用户在房间下的入住信息
//                     AHomeUser homeUser = aHomeUserMapper.selectHomeUserByUserIdAndHomeId(tenantUser.getId(), originalCardKey.getHomeId());
//                     String existingKeyGroupId = null;
//                     if (homeUser != null && StringUtils.isNotEmpty(homeUser.getKeyGroupId())) {
//                         existingKeyGroupId = homeUser.getKeyGroupId();
//                         log.info("找到用户在该房间的入住信息，keyGroupId: " + existingKeyGroupId);
//                     }
//
//                     // 获取原来的开始时间和结束时间（从入住信息中获取）
//                     Long beginTime = null;
//                     Long endTime = null;
//
//                     if (homeUser != null && homeUser.getStartTime() != null) {
//                         beginTime = homeUser.getStartTime().getTime() / 1000; // 转换为秒
//                     }
//                     if (homeUser != null && homeUser.getEndTime() != null) {
//                         endTime = homeUser.getEndTime().getTime() / 1000; // 转换为秒
//                     }
//
//                    log.info("开始添加新卡片钥匙: 房间=" + roomNum + ", 用户=" + tenantUser.getName() +
//                                      ", 新卡号=" + tenantUser.getCardNo() +
//                                      ", 开始时间=" + (homeUser != null ? homeUser.getStartTime() : "未知") +
//                                      ", 结束时间=" + (homeUser != null ? homeUser.getEndTime() : "未知"));
//
//                    // 使用apartmentAddCardKey进行授权
//                    JSONObject authResult = lockApiService.apartmentAddCardKey(
//                        roomNum,                           // 房间号
//                        tenantUser.getPhone(),             // 手机号
//                        tenantUser.getName(),              // 用户姓名
//                        beginTime,                         // 原来的开始时间
//                        endTime,                          // 原来的结束时间
//                        tenantUser.getCardNo(),            // 新卡号
//                        existingKeyGroupId,                // keyGroupId
//                        tenantUser.getIdCardNumber()       // 学工号
//                    );
//
//                    if (authResult != null && authResult.getIntValue("resultCode") == 0) {
//                        // 获取返回的keyGroupId和lockKeyId
//                        String newKeyGroupId = null;
//                        String newLockKeyId = null;
//                        if (authResult.containsKey("data")) {
//                            JSONObject dataObj = authResult.getJSONObject("data");
//                            newKeyGroupId = dataObj.getString("keyGroupId");
////                            newLockKeyId = dataObj.getString("lockKeyId");
//                            newLockKeyId = dataObj.getString("keyId");
//
//                        }
//
//                        if (newKeyGroupId != null) {
//                            // 更新a_home_user的key_group_id
//                            updateKeyGroupIdByUserAndRoom(tenantUser.getId(), originalCardKey.getHomeId(), newKeyGroupId);
//                           log.info("✅ 更新a_home_user的keyGroupId成功: 房间=" + roomNum + ", keyGroupId=" + newKeyGroupId);
//                        }
//
//                        // 创建新的钥匙记录
//                        createNewCardKey(originalCardKey, tenantUser, newKeyGroupId, newLockKeyId);
//                       log.info("✅ 添加新卡片钥匙成功: 房间=" + roomNum + ", lockKeyId=" + newLockKeyId);
//
//                    } else {
//                        String reason = authResult != null ? authResult.getString("reason") : "未知错误";
//                        log.info("❌ 添加新卡片钥匙失败: 房间=" + roomNum + ", 原因=" + reason);
//                    }
//                }
//            }
//        } catch (Exception e) {
//            log.info("❌ 添加新钥匙失败 (学工号: " + userNumb + "): " + e.getMessage());
//            e.printStackTrace();
//        }
//    }

    /**
     * 创建新的钥匙记录
     */
    private void createNewCardKey(ATenantkey originalCardKey, ATenantuser tenantUser, String keyGroupId, String lockKeyId) {
        try {
            ATenantkey newCardKey = new ATenantkey();
            
            // 复制原钥匙的基本信息
            newCardKey.setHomeId(originalCardKey.getHomeId());
            newCardKey.setTenantId(tenantUser.getId());
//            newCardKey.setUserName(tenantUser.getName());
//            newCardKey.setUserPhone(tenantUser.getPhone());

//            newCardKey.setRelation(originalCardKey.getRelation());
            newCardKey.setType("2"); // 卡片类型
//            newCardKey.setStartTime(originalCardKey.getStartTime());
//            newCardKey.setEndTime(originalCardKey.getEndTime());
            newCardKey.setCardNo(tenantUser.getCardNo()); // 新卡号
            newCardKey.setStatus(0); // 有效状态
            newCardKey.setKeyGroupId(keyGroupId);
            newCardKey.setPwdId(lockKeyId);
//            newCardKey.setLockKeyId(lockKeyId);
            newCardKey.setRemark(originalCardKey.getRemark());
            
            // 插入新钥匙记录
            int insertResult = aTenantkeyMapper.insertATenantkey(newCardKey);
           log.info("✅ 创建新钥匙记录成功: " + insertResult + " 行受影响");
            
        } catch (Exception e) {
            log.info("❌ 创建新钥匙记录失败: " + e.getMessage());
            e.printStackTrace();
        }
    }





    /**
     * 更新key_group_id
     */
    private void updateKeyGroupIdByUserAndRoom(Long userId, Long roomId, String keyGroupId) {
        try {
            int updateResult = aHomeUserMapper.updateKeyGroupIdByHomeIdAndUserId(roomId, userId, keyGroupId);
           log.info("✅ 更新key_group_id成功: " + updateResult + " 行受影响");
        } catch (Exception e) {
            log.info("❌ 更新key_group_id失败: " + e.getMessage());
        }
    }

    /**
     * 测试Oracle数据同步功能 - 使用模拟数据
     * 用于验证数据处理逻辑是否正确
     */
    public void testOracleDataSync() {
        try {
           log.info("开始测试Oracle数据同步功能...");
            
            // 创建测试数据列表
            List<SSchoolUser> testUserList = new ArrayList<>();
            
            // 测试用户1：新用户，学生，菱湖校区
            SSchoolUser testUser1 = new SSchoolUser();
            testUser1.setUserId("1111");
            testUser1.setUserName("李文彦42");
            testUser1.setUserNumb("121212");
            testUser1.setSex(1L); // 1=男
            testUser1.setDeptName("测试学校/合肥市第六中学/菱湖校区/高三/2025届3班");
            testUser1.setCategory(28L); // 28=学生
            testUser1.setUserStatus(0L); // 0=正常
            testUser1.setCardNo(null);
//            testUser1.setFactoryFixId("CD3F11C7"); // 十六进制卡号
            testUser1.setFactoryFixId("CC9C5387"); // 十六进制卡号
            testUser1.setCardStatus(1L);
            testUser1.setUpdateTime("2025-02-27 11:30:00");
            testUserList.add(testUser1);
            
            // 测试用户2：新用户，教职工，其他校区
//            SSchoolUser testUser2 = new SSchoolUser();
//            testUser2.setUserId("99998");
//            testUser2.setUserName("测试教师李四");
//            testUser2.setUserNumb("TEST20250127002");
//            testUser2.setSex(2L); // 2=女
//            testUser2.setDeptName("测试学校/合肥市第六中学/本部校区/数学组");
//            testUser2.setCategory(12L); // 非28=教职工
//            testUser2.setUserStatus(0L); // 0=正常
//            testUser2.setCardNo(null);
//            testUser2.setFactoryFixId("EFGH5678"); // 十六进制卡号
//            testUser2.setCardStatus(1L);
//            testUser2.setUpdateTime("2025-01-27 10:35:00");
//            testUserList.add(testUser2);
//
            // 测试用户3：状态注销的用户
//            SSchoolUser testUser3 = new SSchoolUser();
//            testUser3.setUserId("99997");
//            testUser3.setUserName("测试注销用户王五");
//            testUser3.setUserNumb("TEST20250127003");
//            testUser3.setSex(1L); // 1=男
//            testUser3.setDeptName("测试学校/合肥市第六中学/菱湖校区/高二/2026届3班");
//            testUser3.setCategory(28L); // 28=学生
//            testUser3.setUserStatus(1L); // 1=注销
//            testUser3.setCardNo(null);
//            testUser3.setFactoryFixId("1234ABCD"); // 十六进制卡号
//            testUser3.setCardStatus(1L);
//            testUser3.setUpdateTime("2025-01-27 10:40:00");
//            testUserList.add(testUser3);
            
           log.info("创建了 " + testUserList.size() + " 条测试数据");
            
            // 分批处理测试数据
            int batchSize = 1000;
            int totalBatches = (testUserList.size() + batchSize - 1) / batchSize;
            
           log.info("开始分批处理测试数据，总批次数: " + totalBatches + "，每批大小: " + batchSize);
            
            int totalNewUsers = 0;
            int totalUpdatedUsers = 0;
            int totalUnchangedUsers = 0;
            
            for (int batchIndex = 0; batchIndex < totalBatches; batchIndex++) {
                int startIndex = batchIndex * batchSize;
                int endIndex = Math.min(startIndex + batchSize, testUserList.size());
                List<SSchoolUser> batch = testUserList.subList(startIndex, endIndex);
                
               log.info("处理第 " + (batchIndex + 1) + "/" + totalBatches + " 批，数据范围: " + startIndex + "-" + (endIndex - 1));
                
                // 处理当前批次
                BatchResult result = processBatch(batch);
                
                totalNewUsers += result.getNewUsers();
                totalUpdatedUsers += result.getUpdatedUsers();
                totalUnchangedUsers += result.getUnchangedUsers();
                
               log.info("第 " + (batchIndex + 1) + " 批处理完成: 新用户=" + result.getNewUsers() +
                        ", 更新=" + result.getUpdatedUsers() + ", 无变化=" + result.getUnchangedUsers());
            }
            
           log.info("测试数据处理完成！");
           log.info("测试结果总结:");
           log.info("  新用户: " + totalNewUsers + " 条");
           log.info("  需要更新: " + totalUpdatedUsers + " 条");
           log.info("  无变化: " + totalUnchangedUsers + " 条");
            
        } catch (Exception e) {
            log.info("测试Oracle数据同步失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
} 